#include "MainProcess.h"
#include <cstdlib>
#include <iostream>
#include <functional>
#include <locale.h>
#include <fstream>




namespace fs = std::filesystem;



/**
 * @brief 对字符串向量进行排序和去重
 * @param vec 待处理的字符串向量引用
 * @note 先排序后使用unique+erase模式去重，时间复杂度为O(n log n)
 */
void deduplicate(std::vector<std::string>& vec) {
    std::sort(vec.begin(), vec.end());  // 排序以确保重复元素相邻
    vec.erase(std::unique(vec.begin(), vec.end()), vec.end());  // 移除连续重复元素
}

/**
 * @brief 递归获取目录下所有指定扩展名的文件路径
 * @param dir_path 根目录路径
 * @param extension 目标文件扩展名（含点号，如".docx"）
 * @return 包含完整文件路径的向量
 * @note 使用C++17 filesystem库实现，支持深度优先遍历
 */
std::vector<std::string> get_files(const std::string& dir_path, const std::string& extension) {
    std::vector<std::string> files;
    
    try {
        // 验证目录有效性
        if (!fs::exists(dir_path) || !fs::is_directory(dir_path)) {
            std::cerr << "错误: 路径不存在或不是目录" << std::endl;
            return files;
        }
        
        // 递归遍历目录
        for (const auto& entry : fs::recursive_directory_iterator(std::format(R"({})", dir_path))) {
            // 检查是否为常规文件且扩展名为.docx
            if (fs::is_regular_file(entry.path()) && 
                entry.path().extension() == extension) {
                files.push_back(entry.path().string());
            }
        }
    } catch (const std::exception& e) {
        std::cout << "获取文件失败,失败原因：" << e.what() << std::endl;
    }

    return files;
}


std::vector<std::string> getSourceRequirements(const std::unordered_map<std::string, std::vector<std::string>>& retroRelationshipMap, const std::string& target, bool flag){
    // Check if the target exists in the retroRelationshipMap
    std::vector<std::string> resVector;
    resVector.push_back(target); // Add the target to the result vector
    auto it = retroRelationshipMap.find(target);
    if (it != retroRelationshipMap.end()) {
        for (auto& item : it->second) {
            // Check if the item is not empty and add it to the result vector
            if (!item.empty()) {
                if (find(resVector.begin(), resVector.end(), item) != resVector.end()) continue;
                resVector.push_back(item);
                if (flag) {
                    std::vector<std::string> temp = getSourceRequirements(retroRelationshipMap, item);
                    resVector.insert(resVector.end(), temp.begin(), temp.end());    
                }
                
            }
        }
    }

    return resVector; // Return an empty vector if the target is not found.
}


std::vector<std::string> getDownstreamRequirements(const std::unordered_map<std::string, std::vector<std::string>>& retroRelationshipMap, const std::string& target, bool flag) {
    std::vector<std::string> resVector;
    for(auto& [key, value] : retroRelationshipMap) {
        if (value.empty()) {
            continue; // Skip empty vectors
        }

        if (find(value.begin(), value.end(), target) != value.end()) {
            // If the target is found in the vector, add the key to the result vector
            resVector.push_back(key);
            if (flag) {
                std::vector<std::string> tmp = getDownstreamRequirements(retroRelationshipMap, key);
                resVector.insert(resVector.end(), tmp.begin(), tmp.end());
            }
            
        }
    
    }

    return resVector; // Return an empty vector if the target is not found.
}


// 去掉字符串两端的空白字符的函数
std::string trim(const std::string& str) {
    // 查找第一个非空字符的位置
    auto start = std::find_if(
        str.begin(), 
        str.end(),
        [](unsigned char c) { return !std::isspace(c); }
    );

    // 查找最后一个非空字符的位置
    auto end = std::find_if(
        str.rbegin(), 
        str.rend(),
        [](unsigned char c) { return !std::isspace(c); }
    ).base();

    // 返回子字符串，该子字符串不包含开头和结尾的空白字符
    return (start <= end) ? std::string(start, end) : std::string();
}


std::vector<std::string> WriteToDotFile(
    const std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& contentMap, 
    const std::unordered_map<std::string, std::vector<std::string>>& retroRelationshipMap, 
    const std::string& target
) {
    // cout << "write to dot file started" << endl;
    std::vector<std::string> res_vector;
    

    // get the value from contextMap using the target key
    auto it_context = contentMap.find(target);

    // judge if the target exists in the contextMap
    if (it_context == contentMap.end()) {
        std::cout << "Target not found in contextMap." << std::endl;
        return res_vector; // Exit if the target is not found.
    }

    std::string workPath = fs::current_path().string(); // 获取当前工作目录
    DotFileWriter::DotFile dotFileWriter(format("{}/{}.dot", workPath, target)); // Create a DotFileWriter instance with the output file name.
    dotFileWriter.open();
    dotFileWriter.writeHeader(); // Write the header for the DOT file with a graph name.

    // write the target key to the DOT file
    int count = 0; // Initialize a counter for the number of elements in the contextMap.
    std::string nodeName = it_context->first; // Get the target key from the contextMap.
    std::string silLevel = it_context->second.at(SAFETY_KEY); // Get the SIL level from the target key.
    silLevel.empty() ? silLevel = "" : silLevel; // If the SIL level is empty, set it to "SIL0".
    
    dotFileWriter.writeSubgraph(nodeName, trim(silLevel), std::to_string(count++)); // Write a subgraph with the target key and SIL level.
    
    std::vector<std::string> requirements1 = getSourceRequirements(retroRelationshipMap, target); // Get the requirements for the target from the retro relationship map.
    std::vector<std::string> requirements2 = getDownstreamRequirements(retroRelationshipMap, target);
    res_vector.insert(res_vector.end(), requirements1.begin(), requirements1.end()); // Combine the two vectors of requirements.
    res_vector.insert(res_vector.end(), requirements2.begin(), requirements2.end()); // Combine the two vectors of requirements.
    deduplicate(res_vector); // Remove duplicate requirements from the combined vector.
    for (const auto& requirement : res_vector) { // Iterate through the requirements.
        std::string tNodeName = requirement; // Get the requirement node name.
        auto it = contentMap.find(tNodeName); // Find the requirement node in the contextMap.
        if (it != contentMap.end()) { // If the requirement node exists in the contextMap.
            std::string tSILLevel = it->second.at(SAFETY_KEY); // Get the SIL level for the requirement node.
            tSILLevel.empty() ? tSILLevel = "" : tSILLevel; // If the SIL level is empty, set it to "SIL0".
            dotFileWriter.writeSubgraph(tNodeName, trim(tSILLevel), std::to_string(count++)); // Write a subgraph for the requirement node with its SIL level.
        }
    }

    for (auto const& item : std::as_const(res_vector)) { // Iterate through the requirements again.
        std::string tNodeName = item; // Get the requirement node name.
        auto it = retroRelationshipMap.find(tNodeName); // Find the requirement node in the contextMap.
        if (it != retroRelationshipMap.end()) { // If the requirement node exists in the contextMap.
            std::string sources = "";
            int count = 0;
            for(auto const& source : it->second) { // Iterate through the retro relationship map for the requirement node.
                if (source.empty() || std::find(res_vector.begin(), res_vector.end(), source) == res_vector.end()) {
                    continue; // Skip if the source is not in the requirements vector.
                }
                if (count++ > 0) {
                    sources += format(" \"{}\"", source); // Append the requirement node to the sources string.
                } else {
                    sources += format("\"{}\"", source); // Append the requirement node to the sources string.
                }
                
            }
            std::string Node; 
            (tNodeName.empty() || sources.empty()) ? (void()) : ( Node = (tNodeName == target)? format("\"{}\"[style=filled, fillcolor=fuchsia]\n\"{}\" -> {{{}}}", tNodeName, tNodeName, sources) : format("\"{}\" -> {{{}}}", tNodeName, sources) , dotFileWriter.writeNode(Node)); // Create a string representing the relationship between the target and the requirement node.
        }
    }

    dotFileWriter.writeEnd(); // Write the end of the DOT file.
    dotFileWriter.close(); // Close the DOT file after writing.
    // cout << "write to dot file finished" << endl;
    return res_vector;
}


// Function to run the main logic of reading DOCX files from a directory
void run(const std::string& dirPath, const std::string& target, const bool& accept_flag, const bool& client_Flag, const bool& search_flag) {
    MemoryShared::MemoryMapping mem;
    std::unordered_map<std::string, std::unordered_map<std::string, std::string>> contentMap;
    std::unordered_map<std::string, std::vector<std::string>> retroRelationshipMap;

    if (!client_Flag) {
        std::vector<std::string> docx_files = get_files(fs::absolute(fs::path(dirPath)).string(), ".docx"); // Get all DOCX files in the specified directory.
        if (docx_files.empty()) {
            std::cout << "No DOCX files found in the specified directory." << std::endl;
            return; // Exit if no DOCX files are found.
        }

        
        for(const auto& file : docx_files) {
            if (accept_flag) {
                std::cout << "正在修改文档属性:" << file << std::endl;
                changeDocxAttributes(file);
            }
            std::cout << "正在读取文档:" << file << std::endl;
            FileReader::DocxFileReader reader(file); 
            reader.openFile();  // Attempt to open the DOCX file.
            reader.readAll(); // Read all content from the DOCX file.
            std::unordered_map<std::string, std::unordered_map<std::string, std::string>> tContentMap = reader.getAllRequirements();
            FileReader::DocxFileReader::concatenateMaps<std::unordered_map<std::string, std::string>>(contentMap, tContentMap);

            std::unordered_map<std::string, std::vector<std::string>> tRetroRelationshipMap = reader.getRetroRelationship();
            FileReader::DocxFileReader::concatenateMaps<std::vector<std::string>>(retroRelationshipMap, tRetroRelationshipMap);
        }

        std::vector<std::string> xlsx_files = get_files(fs::absolute(fs::path(dirPath)).string(), ".xlsx"); // Get all DOCX files in the specified directory.
        if (xlsx_files.empty()) {
            std::cout << "No XLSX files found in the specified directory." << std::endl;
            return; // Exit if no DOCX files are found.
        }

        for (auto const& file : xlsx_files) { // Iterate through the XLSX files.
            std::unordered_map<std::string, std::unordered_map<std::string, std::string>> tContentMap = 
            FileReader::ExcelFileReader::read(file); // Create an instance of XlsxFileReader.
            FileReader::DocxFileReader::concatenateMaps<std::unordered_map<std::string, std::string>>(contentMap, tContentMap);
        }

        // for (auto m : contentMap) { // Iterate through the context map.
        //     for (auto n : m.second) { // Iterate through the inner unordered_map.
        //         std::cout << "  Sub Key: " << n.first << ", Value: " << n.second << std::endl; // Print the sub key and its value.
        //     }
        // }

    // for (auto m : retroRelationshipMap) { // Iterate through the retro relationship map.
    //     cout << "Key: " << m.first << endl; // Print the key of the retro relationship map.
    //     for (const auto& n : m.second) { // Iterate through the vector of strings.
    //         cout << "  Value: " << n << endl; // Print each value in the vector.
    //     }
    // }
        mem.createMemory();
        writeContentMapToSharedMem(mem, contentMap);
        writeRetroMapToSharedMem(mem, retroRelationshipMap);
    } else {
        std::cout << "正在等待主进程读取完成，请稍后...";
        while(!mem.openMemory()){ Sleep(1000); }
        std::cout << std::endl;
        std::unordered_map<std::string, std::unordered_map<std::string, std::string>> tContentMap = readContentMapFromSharedMem(mem);
        FileReader::DocxFileReader::concatenateMaps<std::unordered_map<std::string, std::string>>(contentMap, tContentMap);

        std::unordered_map<std::string, std::vector<std::string>> tRetroRelationshipMap = readRetroMapFromSharedMem(mem);      
        FileReader::DocxFileReader::concatenateMaps<std::vector<std::string>>(retroRelationshipMap, tRetroRelationshipMap);
        // for (auto m : contentMap) { // Iterate through the context map.
        // // if(m.first == "OBCU_SuRS_6365") {
        //     std::cout << "Key: " << m.first << std::endl; // Print the key of the context map.
        //     for (auto n : m.second) { // Iterate through the inner unordered_map.
        //             std::cout << "  Sub Key: " << n.first << ", Value: " << n.second << std::endl; // Print the sub key and its value.
        //         }
        //     // }
        // }

    // for (auto m : retroRelationshipMap) { // Iterate through the retro relationship map.
    //     cout << "Key: " << m.first << endl; // Print the key of the retro relationship map.
    //     for (const auto& n : m.second) { // Iterate through the vector of strings.
    //         cout << "  Value: " << n << endl; // Print each value in the vector.
    //     }
    // }

    }

    if (!search_flag) {
        // If the prefix flag is set, modify the target by adding a prefix.
        std::vector<std::string> res_vector = getAllRequirementsList(contentMap, retroRelationshipMap, target); // Get all requirements related to the target.
        if (res_vector.size() > 0) {
            try {
                createVerificationSheets(contentMap, retroRelationshipMap, res_vector, dirPath);
            } catch (...) {
                std::cerr << "create excel failed" << std::endl;
            }
        } else {
            std::cout << "未匹配到目标" << std::endl;
        }
    } else {
        std::vector<std::string> res_vector = WriteToDotFile(contentMap, retroRelationshipMap, target); // Write the context map and retro relationship map to a DOT file.

        if (res_vector.size() > 0) {
            try {
                transferToPng(dirPath, target);
            } catch (...) {
                std::cerr << "png transfer failed" << std::endl;
            }
            
            removeDotFile(target); // Remove the generated DOT file after processing.

            try {
                writeToExcel(contentMap, retroRelationshipMap, res_vector, dirPath, target);
            } catch (...) {
                std::cerr << "create excel failed" << std::endl;
            }
        } else {
            std::cout << "未匹配到目标" << std::endl;
        }
    }

    if (!client_Flag) Sleep(1000);
}


void transferToPng(const std::string& path, const std::string& target) {
    // This function is not implemented in this snippet.
    // It should transfer the generated DOT file to a PNG file.
    // For now, we do nothing.
    // 要执行的命令及参数
    
    std::string workPath = fs::current_path().string(); // 获取当前工作目录
    fs::path execute_path = fs::current_path()/"bin/dot.exe"; // 获取可执行程序所在目录
    // std::string executable = format(R"({}\bin\dot.exe)", workPath);  // 可执行程序路径
    fs::path out_path = fs::absolute(path)/format("{}.png", target);
    // std::string arg = format(R"(-Tpng output.dot -o "{}\graph.png")",fs::absolute(path).string());               // 参数

    // 构建完整命令
    std::string command = format(R"("{}" {} {})", execute_path.string(), format("-Tpng {}/{}.dot -o", workPath, target) ,out_path.string());
    // cout << command;
    int result = system(command.c_str()); // 执行命令
    if (result == 0) {
        std::cout << format(R"(图片输出路径:{}\{}.png)", fs::absolute(path).string(), target)<< std::endl;
    } else {
        std::cerr << "Failed to execute command: " << command << std::endl;
    }
      
}


void removeDotFile(const std::string& target) {
    // Remove the generated DOT file if it exists
    std::string workPath = fs::current_path().string();
    std::filesystem::path dotFilePath(std::format("{}/{}.dot", workPath, target));
    if (std::filesystem::exists(dotFilePath)) {
        std::filesystem::remove(dotFilePath);
    }
}



void writeToExcel(
    const std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& contentMap, 
    std::unordered_map<std::string, std::vector<std::string>> retroRelationshipMap,
    const std::vector<std::string>& target_list,
    const std::string& path,
    const std::string& target)
{
    /* Create a workbook and add a worksheet. */
    // setlocale(LC_ALL, "zh_CN.UTF-8"); 
    fs::path out_path = fs::absolute(path)/std::format("{}.xlsx", target);
    // 检查输出路径是否存在，如果存在则删除
    if (fs::exists(out_path)) {
        fs::remove(out_path); // 删除已存在的文件
    }
    // 创建新的工作簿
    xlnt::workbook wb;  
    
    xlnt::worksheet ws = wb.sheet_by_index(0); // 创建一个新的工作表
    
    // 设置工作表名称
    ws.title("result");

    ws.column_properties(1).width = 30; // 设置第一列宽度
    ws.column_properties(2).width = 50; // 设置第二列宽度
    ws.column_properties(3).width = 30; // 设置第三列宽度
    ws.column_properties(4).width = 30; // 设置第四列宽度

    int row = 1; // 从第一行开始写入数据
    int col = 1; // 从第一列开始写入数据

    xlnt::alignment alignment; // 创建一个对齐对象
    alignment.wrap(true); // 设置单元格自动换行
    alignment.horizontal(xlnt::horizontal_alignment::center); // 设置单元格内容水平居中

    

    std::vector<std::string> title = {"ID", "DESCRIPTION", "SIL_LEVEL", "REQUIREMENT TYPE"};
    for(const auto& item : std::as_const(title)) {
        ws.cell(col, row).alignment(alignment); // 设置单元格自动换行和水平居中
        ws.cell(col, row).value(item); // 写入标题
        col++;
    }
    row++; // 移动到下一行

    
    MyXlnt::Decorator_Worksheet decorator(&ws); // 创建一个装饰器对象，用于设置工作表的样式
    for(const auto& key : std::as_const(target_list)) {
        col = 1;
        auto it = contentMap.find(key);
        if(it != contentMap.end()){
            decorator.writeWithWrap(col++, row, key); // 使用装饰器写入ID
            auto description = it->second.find(DESCRIPTION_KEY);
            if(description != it->second.end()) {
                decorator.writeWithWrap(col++, row, description->second); // 使用装饰器写入ID
            } else {
                col++;
            }
            
            auto silLvl = it->second.find(SAFETY_KEY);
            if(silLvl != it->second.end()) {
                decorator.writeWithWrap(col++, row, silLvl->second); // 使用装饰器写入ID
            } else {
                col++;
            }
            // std::string type = it->second.at(TYPE_KEY);
            auto type = it->second.find(TYPE_KEY);
            if(type != it->second.end()) {
                decorator.writeWithWrap(col++, row, type->second); // 使用装饰器写入ID
            } else {
                col++;
            }
            ++row;
        }
    }

    xlnt::worksheet ws2 = wb.create_sheet(); // 创建一个新的工作表
    setupExcelSheet(&ws2, "Completeness"); // 设置工作表名称

    xlnt::worksheet ws3 = wb.create_sheet(); // 创建一个新的工作表
    setupExcelSheet(&ws3, "Traceability"); // 设置工作表名称
    ws3.title("Traceability"); // 设置工作表名称

    row = 1; // 从第一行开始写入数据
    col = 1; // 从第一列开始写入数据

    writeCompleteness(&ws2, contentMap, retroRelationshipMap, target_list);
    writeTraceability(&ws3, contentMap, retroRelationshipMap, target_list);

    wb.save(out_path); // 保存工作簿到指定路径

    std::cout <<std::format(R"(表格输出路径:{}\{}.xlsx)", fs::absolute(path).string(), target)<< std::endl;

}


void setupExcelSheet(xlnt::worksheet* const worksheet, const std::string& sheetName){
    worksheet->title(sheetName); // 设置工作表名称

    worksheet->column_properties(1).width = 30; // 设置第一列宽度
    worksheet->column_properties(2).width = 50; // 设置第二列宽度
    worksheet->column_properties(3).width = 30; // 设置第三列宽度
    worksheet->column_properties(4).width = 30; // 设置第四列宽度
    worksheet->column_properties(5).width = 30; // 设置第一列宽度
    worksheet->column_properties(6).width = 50; // 设置第二列宽度
    worksheet->column_properties(7).width = 30; // 设置第三列宽度
    worksheet->column_properties(8).width = 30; // 设置第四列宽度

    int row = 1;
    int col = 1;

    xlnt::alignment alignment; // 创建一个对齐对象
    alignment.wrap(true); // 设置单元格自动换行
    alignment.horizontal(xlnt::horizontal_alignment::center); // 设置单元格内容水平居中

    std::vector<std::string> title = {"ID", "DESCRIPTION", "SIL_LEVEL", "REQUIREMENT TYPE"};
    for(const auto& item : std::as_const(title)) {
        worksheet->cell(col, row).alignment(alignment); // 设置单元格自动换行和水平居中
        worksheet->cell(col, row).value(item); // 写入标题
        worksheet->cell(col + 4, row).alignment(alignment); // 设置单元格自动换行和水平居中
        worksheet->cell(col + 4, row).value(item); // 写入标题
        col++;
    }
}


void writeCompleteness(
    xlnt::worksheet* worksheet, 
    const std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& contentMap, 
    std::unordered_map<std::string, std::vector<std::string>> retroRelationshipMap,
    const std::vector<std::string>& target_list)
{
    int row = 2;
    int col = 1;

    xlnt::alignment alignment; // 创建一个对齐对象
    alignment.wrap(true); // 设置单元格自动换行

    MyXlnt::Decorator_Worksheet decorator(worksheet); // 创建一个装饰器对象，用于设置工作表的样式

    for ( auto const& item : std::as_const(target_list) ) {
        col = 1;
        auto it = contentMap.find(item);
        if(it != contentMap.end()){
            decorator.writeWithWrap(col++, row, item); // 使用装饰器写入ID

            auto source_des = it->second.find(DESCRIPTION_KEY);
            if (source_des != it->second.end()) {
                decorator.writeWithWrap(col++, row, source_des->second); // 使用装饰器写入ID
            } else {
                col++;
            }
            auto source_safety = it->second.find(SAFETY_KEY);
            if (source_safety != it->second.end()) {
                decorator.writeWithWrap(col++, row, source_safety->second); // 使用装饰器写入ID
            } else {
                col++;
            }
            auto source_type = it->second.find(TYPE_KEY);
            if (source_type != it->second.end()) {
                decorator.writeWithWrap(col++, row, source_type->second); // 使用装饰器写入ID
            } else {
                col++;
            }

            // 写入下游需求
            std::vector<std::string> downstream = getDownstreamRequirements(retroRelationshipMap, item, false);
            std::string id_str, description_str, silLvl_str, type_str;
            for (auto const& subItem : std::as_const(downstream)) {
                auto subIt = contentMap.find(subItem);
                if (subIt != contentMap.end()) {
                    id_str += subItem + "\n\n";
                
                    auto description = subIt->second.find(DESCRIPTION_KEY);
                    if(description != subIt->second.end()) {
                        description_str += trim(description->second) + "\n\n";
                    }

                    auto silLvl = subIt->second.find(SAFETY_KEY);
                    if(silLvl != subIt->second.end()) {
                        silLvl_str += trim(silLvl->second) + "\n\n";
                    } 
                    // std::string type = it->second.at(TYPE_KEY);
                    auto type = subIt->second.find(TYPE_KEY);
                    if(type != subIt->second.end()) {
                        type_str += trim(type->second) + "\n\n";
                    } 
                }
            }

            decorator.writeWithWrap(col++, row, id_str); // 使用装饰器写入ID
            decorator.writeWithWrap(col++, row, description_str); // 写入描述
            decorator.writeWithWrap(col++, row, silLvl_str); // 写入安全等级
            decorator.writeWithWrap(col++, row, type_str); // 写入类型
            ++row;

        }

    }
}



void writeTraceability(
    xlnt::worksheet*  worksheet, 
    const std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& contentMap, 
    std::unordered_map<std::string, std::vector<std::string>> retroRelationshipMap,
    const std::vector<std::string>& target_list)
{
    /* Start from the first cell. Rows and columns are zero indexed. */
    int row = 2;
    int col = 1;

    xlnt::alignment alignment; // 创建一个对齐对象
    alignment.wrap(true); // 设置单元格自动换行

    MyXlnt::Decorator_Worksheet decorator(worksheet); // 创建一个装饰器对象，用于设置工作表的样式
    
    for (auto const& item : std::as_const(target_list)) {
        auto it_info = contentMap.find(item);
        auto it_retro = retroRelationshipMap.find(item);
        col = 1;
        if (it_info != contentMap.end() && it_retro != retroRelationshipMap.end()) {
            decorator.writeWithWrap(col++, row, item); // 使用装饰器写入ID
            auto des = it_info->second.find(DESCRIPTION_KEY);
            if (des != it_info->second.end()) {
                decorator.writeWithWrap(col++, row, des->second); // 使用装饰器写入ID
            }
            auto safety = it_info->second.find(SAFETY_KEY);
            if (safety != it_info->second.end()) {
                decorator.writeWithWrap(col++, row, safety->second); // 使用装饰器写入ID
            }
            auto type = it_info->second.find(TYPE_KEY);
            if (type != it_info->second.end()) {
                decorator.writeWithWrap(col++, row, type->second); // 使用装饰器写入ID
            }

            std::vector<std::string> upstream = getSourceRequirements(retroRelationshipMap, item, false);
            std::string id_str, description_str, silLvl_str, type_str;

            for (auto const& subItem : std::as_const(upstream)) {
                if (subItem == item) continue;
                auto subIt = contentMap.find(subItem);
                if (subIt != contentMap.end()) {
                    id_str += subItem + "\n\n";
                
                    auto description = subIt->second.find(DESCRIPTION_KEY);
                    if(description != subIt->second.end()) {
                        description_str += trim(description->second) + "\n\n";
                    }

                    auto silLvl = subIt->second.find(SAFETY_KEY);
                    if(silLvl != subIt->second.end()) {
                        silLvl_str += trim(silLvl->second) + "\n\n";
                    } 
                    // std::string type = it->second.at(TYPE_KEY);
                    auto type = subIt->second.find(TYPE_KEY);
                    if(type != subIt->second.end()) {
                        type_str += trim(type->second) + "\n\n";
                    } 
                }
            }

            decorator.writeWithWrap(col++, row, id_str); // 使用装饰器写入ID
            decorator.writeWithWrap(col++, row, description_str); // 写入描述
            decorator.writeWithWrap(col++, row, silLvl_str); // 写入安全等级
            decorator.writeWithWrap(col++, row, type_str); // 写入类型
            ++row;

        }

    }
}

void changeDocxAttributes(const std::string& path) {
    // This function is not implemented in this snippet.
    // It should transfer the generated DOT file to a PNG file.
    // For now, we do nothing.
    // 要执行的命令及参数
    fs::path execute_path = fs::current_path()/"bin/docx_processor.exe"; // 获取可执行程序所在目录

    STARTUPINFOW si = {sizeof(si)};
    PROCESS_INFORMATION pi = {0};

    // Convert std::string to std::wstring for wide-character API
    std::wstring w_execute_path = std::filesystem::path(execute_path).wstring();
    std::wstring w_args = std::filesystem::path(path).wstring();
    std::wstring commandLine = L"\"" + w_execute_path + L"\" \"" + w_args + L"\"";

    BOOL success = CreateProcessW(
        w_execute_path.c_str(),
        &commandLine[0],
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        NULL,
        &si,
        &pi
    );
    if (success) {
        WaitForSingleObject(pi.hProcess, INFINITE);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    } else {
        std::wcerr << "Failed to execute command: " << commandLine << std::endl;
    }
      
}




void writeContentMapToSharedMem(
    MemoryShared::MemoryMapping& mem,
    std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& data)
{
    mem.writeTotalSize(data.size());
    int n = 0;
    for(auto const& [key, value] : data) {
        if (key.empty()) continue;

        const char* name_data = key.c_str();
        long name_size = strlen(name_data) + 1;
        mem.write(name_size, name_data);

        if (value.find(SAFETY_KEY) == value.end()) {

        }
        const char* safety_data = value.at(SAFETY_KEY).c_str();
        long safety_size = strlen(safety_data) + 1;
        mem.write(safety_size, safety_data);

        const char* type_data = value.at(TYPE_KEY).c_str();
        long type_size = strlen(type_data) + 1;
        mem.write(type_size, type_data);

        const char* description_data = value.at(DESCRIPTION_KEY).c_str();
        long description_size = strlen(description_data) + 1;
        mem.write(description_size, description_data);

    }
}

std::unordered_map<std::string, std::unordered_map<std::string, std::string>> readContentMapFromSharedMem(MemoryShared::MemoryMapping& mem) 
{
    
    std::unordered_map<std::string, std::unordered_map<std::string, std::string>> res;
    
    long size = mem.readTotalSize();
    for (int n = 0; n < size; n++) {
        std::unordered_map<std::string, std::string> item;

        char* name_size = mem.read(sizeof(long));
        char* name = mem.read(*reinterpret_cast<long*>(name_size));
        char* safety_size = mem.read(sizeof(long));
        char* safety = mem.read(*reinterpret_cast<long*>(safety_size));
        item[SAFETY_KEY] = std::string(safety);

        char* type_size = mem.read(sizeof(long));
        char* type = mem.read(*reinterpret_cast<long*>(type_size));
        item[TYPE_KEY] = std::string(type);

        char* description_size = mem.read(sizeof(long));
        char* description = mem.read(*reinterpret_cast<long*>(description_size));
        item[DESCRIPTION_KEY] = std::string(description);


        res[name] = item;
    }

    return res;
}


void writeRetroMapToSharedMem(
    MemoryShared::MemoryMapping& mem,
    std::unordered_map<std::string, std::vector<std::string>>& data)
{
    mem.writeTotalSize(data.size());
    for(auto const& [key, value] : data) {
        const char* name_data = key.c_str();
        int name_size = strlen(name_data) + 1;
        mem.write(name_size, name_data);
        mem.writeTotalSize(value.size());
        for(auto const& item : value) {
            const char* data = item.c_str();
            int size = strlen(data) + 1;
            mem.write(size, data);
        }
    }
}

std::unordered_map<std::string, std::vector<std::string>> readRetroMapFromSharedMem(MemoryShared::MemoryMapping& mem)
{
    std::unordered_map<std::string, std::vector<std::string>> res;
    int size = mem.readTotalSize();
    for (int n = 0; n < size; n++) {
        char* name_size = mem.read(sizeof(int));
        char* name = mem.read(*reinterpret_cast<long*>(name_size));

        std::vector<std::string> vec;
        int sub_size = mem.readTotalSize();
        for (int i = 0; i < sub_size; i++) {
            char* data_size = mem.read(sizeof(int));
            char* data = mem.read(*reinterpret_cast<long*>(data_size));
            vec.push_back(std::string(data));
        }

        res[name] = vec;
    }
    return res;
}

std::vector<std::string> getAllRequirementsList(
    const std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& contentMap, 
    std::unordered_map<std::string, std::vector<std::string>> retroRelationshipMap,
    const std::string& target)
{
    // cout << "write to dot file started" << endl;
    std::vector<std::string> res_vector;
    for (auto const& [key, value] : std::as_const(contentMap)) { // Iterate through the contentMap.
        if (key.find(target) != std::string::npos) { // If the key matches the target.
            res_vector.push_back(key); // Add the key to the result vector.
        }
    }

    return res_vector;
}


void createVerificationSheets(
    const std::unordered_map<std::string, std::unordered_map<std::string, std::string>>& contentMap, 
    std::unordered_map<std::string, std::vector<std::string>> retroRelationshipMap,
    const std::vector<std::string>& target_list,
    const std::string& path)
{
    if (target_list.empty()) {
        std::cout << "目标列表为空，无法创建工作表。" << std::endl;
        return;
    }
    std::regex pattern(R"((.*)[_-]\d+)"); // 正则表达式模式，匹配合法的工作表名称
    std::string fileNameSource = target_list[0]; // 使用第一个目标作为工作表名称
    std::smatch match;
    std::string fileName;
    std::regex_search(fileNameSource, match, pattern); // 使用正则表达式匹配工作表名称
    if (match.size() > 1) {
        fileName = match[1]; // 如果匹配成功，使用匹配的第一个子字符串作为工作表名称
    } else {
        std::cout << "目标名称不符合预期格式，无法创建工作表。" << std::endl;
        return;
    }


    fs::path out_path = fs::absolute(path)/std::format("{}.xlsx", fileName);
    // Create a workbook and add a worksheet.
    xlnt::workbook wb;

    auto ws1 = wb.sheet_by_index(0);
    setupExcelSheet(&ws1, "Traceability"); // Create a worksheet with the specified name.

    auto ws2 = wb.create_sheet();
    setupExcelSheet(&ws2, "Completeness"); // Create a worksheet with the specified name.

    writeTraceability(&ws1, contentMap, retroRelationshipMap, target_list);
    writeCompleteness(&ws2, contentMap, retroRelationshipMap, target_list);
    

    // int row = 1;
    // int col = 1;

    // row++;
    // MyXlnt::Decorator_Worksheet decorator1(&ws1); // Create a decorator object for the worksheet.
    // MyXlnt::Decorator_Worksheet decorator2(&ws2); // Create a decorator object for the worksheet.
    // for(auto const& item : std::as_const(target_list)) {
    //     col = 1;
    //     auto it = contentMap.find(item);
    //     auto it_retro = retroRelationshipMap.find(item);
    //     if(it != contentMap.end()){
    //         decorator1.writeWithWrap(col, row, item); // 使用装饰器写入ID
    //         decorator2.writeWithWrap(col++, row, item); // 使用装饰器写入ID
    //         auto des = it->second.find(DESCRIPTION_KEY);
    //         if (des != it->second.end()) {
    //             decorator1.writeWithWrap(col, row, des->second); // 使用装饰器写入ID
    //             decorator2.writeWithWrap(col++, row, des->second); // 使用装饰器写入ID
    //         } else {
    //             col++;
    //         }
    //         auto safety = it->second.find(SAFETY_KEY);
    //         if (safety != it->second.end()) {
    //             decorator1.writeWithWrap(col, row, safety->second); // 使用装饰器写入ID
    //             decorator2.writeWithWrap(col++, row, safety->second); // 使用装饰器写入ID
    //         } else {
    //             col++;
    //         }
    //         auto type = it->second.find(TYPE_KEY);
    //         if (type != it->second.end()) {
    //             decorator1.writeWithWrap(col, row, type->second); // 使用装饰器写入ID
    //             decorator2.writeWithWrap(col++, row, type->second); // 使用装饰器写入ID
    //         } else {
    //             col++;
    //         } 
    //     }
    //     if (it_retro != retroRelationshipMap.end()) {
    //         std::vector<std::string> upstream = it_retro->second; // Get the upstream requirements for the current item.
    //         std::string id_str, description_str, silLvl_str, type_str;
    //         for (auto const& subItem : std::as_const(upstream)) {
    //             if (subItem == item) continue;
    //             auto subIt = contentMap.find(subItem);
    //             if (subIt != contentMap.end()) {
    //                 id_str += subItem + "\n\n";
    //                 auto description = subIt->second.find(DESCRIPTION_KEY);
    //                 if(description != subIt->second.end()) {
    //                     description_str += trim(description->second) + "\n\n";
    //                 }

    //                 auto silLvl = subIt->second.find(SAFETY_KEY);
    //                 if(silLvl != subIt->second.end()) {
    //                     silLvl_str += trim(silLvl->second) + "\n\n";
    //                 } 
    //                 auto type = subIt->second.find(TYPE_KEY);
    //                 if(type != subIt->second.end()) {
    //                     type_str += trim(type->second) + "\n\n";
    //                 } 
    //             }
    //         }

    //         decorator1.writeWithWrap(col++, row, id_str); // 使用装饰器写入上游需求
    //         decorator1.writeWithWrap(col++, row, description_str); // 使用装饰器写入上游需求
    //         decorator1.writeWithWrap(col++, row, silLvl_str); // 使用装饰器写入上游需求
    //         decorator1.writeWithWrap(col++, row, type_str); // 使用装饰器写入上游需求
    //     }
    //     ++row;
    // }

    // /* Start from the first cell. Rows and columns are zero indexed. */
    // row = 2;

    // for (auto const& item : std::as_const(target_list)) {
    //     col = 5;
    //     // 写入下游需求
    //     std::vector<std::string> downstream;
    //     for (auto const& [key, value] : std::as_const(retroRelationshipMap)) {
    //         for (auto const& subItem : std::as_const(value)) {
    //             if (subItem == item) {
    //                 downstream.push_back(key); // Collect all downstream requirements related to the current item.
    //             }
    //         }
    //     }

    //     std::string id_str, description_str, silLvl_str, type_str;
    //     for (auto const& subItem : std::as_const(downstream)) {
    //         auto subIt = contentMap.find(subItem);
    //         if (subIt != contentMap.end()) {
    //             id_str += subItem + "\n\n";

    //             auto description = subIt->second.find(DESCRIPTION_KEY);
    //             if(description != subIt->second.end()) {
    //                 description_str += trim(description->second) + "\n\n";
    //             }

    //             auto silLvl = subIt->second.find(SAFETY_KEY);
    //             if(silLvl != subIt->second.end()) {
    //                 silLvl_str += trim(silLvl->second) + "\n\n";
    //             } 
    //             // std::string type = it->second.at(TYPE_KEY);
    //             auto type = subIt->second.find(TYPE_KEY);
    //             if(type != subIt->second.end()) {
    //                 type_str += trim(type->second) + "\n\n";
    //             } 
    //         }
    //     }

    //     decorator2.writeWithWrap(col++, row, id_str); // 使用装饰器写入上游需求
    //     decorator2.writeWithWrap(col++, row, description_str); // 使用装饰器写入上游需求
    //     decorator2.writeWithWrap(col++, row, silLvl_str); // 使用装饰器写入上游需求
    //     decorator2.writeWithWrap(col++, row, type_str); // 使用装饰器写入上游需求

    //     ++row;
    // }

    wb.save(out_path); // Save the workbook to the specified path.

    std::cout <<std::format(R"(表格输出路径:{}\{}.xlsx)", fs::absolute(path).string(), fileName)<< std::endl;

}


void readConfig(const std::string& filePath){
    using js = nlohmann::json;

    std::ifstream file(filePath);

    if (file.is_open()) {
        js data = js::parse(file);

        js docx = data["DOCX"];
        begin_prefix_str = docx["BEGIN_PREFIX"];
        end_prefix_str = docx["END_PREFIX"];
        
        for(auto const& item : std::as_const(docx["SAFETY_KEY"])) {
            if (item != docx["SAFETY_KEY"].back()) safety_key_str += std::format("{}|", std::string(item));
            else safety_key_str += item;
        }

        for(auto const& item : std::as_const(docx["SIL_0_VALUE"])) {
            sil_0_vector.push_back(item);
        }

        for(auto const& item : std::as_const(docx["SIL_2_VALUE"])) {
            sil_2_vector.push_back(item);
        }

        for(auto const& item : std::as_const(docx["SIL_4_VALUE"])) {
            sil_4_vector.push_back(item);
        }

        for(auto const& item : std::as_const(docx["TYPE_KEY"])) {
            if (item != docx["TYPE_KEY"].back()) type_key_str += std::format("{}|", std::string(item));
            else type_key_str += item;
        }

        for(auto const& item : std::as_const(docx["SOURCE_KEY"])) {
            if (item != docx["SOURCE_KEY"].back()) source_key_str += std::format("{}|", std::string(item));
            else source_key_str += item;
        }
    } else {
        std::cout << "配置文件打开失败!" << std::endl;
    }
    
}


